home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_20 / crack.c next >
C/C++ Source or Header  |  1995-01-01  |  4KB  |  106 lines

  1. /*
  2.  * crack - put the command line to the vice.
  3.  *
  4.  * This routine takes four arguments, the variables argc and argv from
  5.  * the program's main procedure, a list of flags to recognize, and an
  6.  * indication whether to ignore unknown flags or not.
  7.  *
  8.  * The action of crack is to read a command line laid out in the format:
  9.  *
  10.  * % command [flags]... [files]...
  11.  *
  12.  * where the flags are of the form -foption, that is, a minus, a character
  13.  * and an optional argument, butted up to the character.  No space may
  14.  * appear between any flag and its option.  The first command line
  15.  * argument not preceeded by '-' is taken as the end of the flags and the
  16.  * beginning of file names.
  17.  * 
  18.  * The flags argument to crack looks like this: "a|b|cd" for flags a b c
  19.  * and d.  In this example, a and b take (optional!) options, as specified
  20.  * by the trailing colon, c and d do not.  When crack scans a flag, it
  21.  * returns the flag character after setting the external character pointer
  22.  * arg_option to the option part.  It also sets arg_index to the index of
  23.  * the argv variable scanned.  Crack returns NULL when it has scanned the
  24.  * last flag.  The value of arg_index then points at the first 
  25.  * argument after the last flag, which should be the first filename, if
  26.  * any.  If there are no arguments, or no more arguments after reading 
  27.  * the flags, arg_index == argc;
  28.  *
  29.  * Flags may be concatenated, for instance, using the flags argument
  30.  * given above: -cd will treat c and d as
  31.  * flags.  -cdaoption also works.  However, tacking what you think is
  32.  * a flag after another flag that takes an option will cause the flag to
  33.  * be lost.  I.e., -ac will treat c as an option, not a flag.
  34.  * 
  35.  * When the ignore flag is zero,  flags scanned that are not in the flags
  36.  * variable generate an error message and crack returns EOF.  If ignore is
  37.  * nonzero, unknown flags are suppressed, that is, no flag is returned.
  38.  * The purpose of ignoring flags is so that more than one part of a
  39.  * program can scan the command line without having to know about the
  40.  * flags of all the other parts.  For instance, where a program calculates
  41.  * a sampling rate by one flag and a value in seconds in another, it must
  42.  * search for the sampling rate first, then the time value.  Two calls to
  43.  * crack() would be required, one to scan just for the flag setting sampling
  44.  * rate, another to ignore the rate flag, but to set the time value based
  45.  * on the sampling rate.
  46.  * NOTE: WHEN MAKING MORE THAN ONE CALL TO crack() IN A PROGRAM, IT
  47.  * IS NECESSARY TO RESET arg_index TO 0 FIRST.
  48.  *
  49.  * When ignoring unknown flags, if an unknown flag has an option
  50.  * associated with it, the option is also ignored.  Care should be excercised
  51.  * here because it may be possible that the associated "option" is really
  52.  * more concatenated flags.  These, if any, are lost.  The rule is that,
  53.  * when ignoring unknown flags, the first instance of an unknown flag
  54.  * causes that flag and the rest of that argument to be discarded.  For
  55.  * instance, if flags is set to "a:b:cd", and a command line:
  56.  * "-zcdaoption" is supplied, c d and a would be ignored because they come
  57.  * after z in the same argument.  The point is there is no way to disambiguate
  58.  * flags from unknown options when ignoring flags, so concatenating options,
  59.  * while nice, is problematical.
  60.  */
  61.  
  62. #include <stdio.h>
  63.  
  64. int arg_index = 0;
  65. char *arg_option;
  66. char *pvcon = NULL;
  67.  
  68. char crack(argc, argv, flags, ign)
  69.     int argc; char **argv; char *flags; int ign;
  70. {
  71.     char *pv, *flgp, *strchr();
  72.     while ((arg_index) < argc)
  73.     {
  74.     if (pvcon != NULL)
  75.         pv = pvcon;
  76.     else
  77.         {
  78.         if (++arg_index >= argc) return(NULL); 
  79.         pv = argv[arg_index];
  80.         if (*pv != '-') 
  81.         return(NULL);
  82.         }
  83.     pv++;        /* skip '-' or prev. flag */
  84.     if (*pv != NULL)
  85.         {
  86.         if ((flgp=strchr(flags,*pv)) != NULL)
  87.         {
  88.         pvcon = pv;
  89.         if (*(flgp+1) == '|') { arg_option = pv+1; pvcon = NULL; }
  90.         return(*pv);
  91.         }
  92.         else
  93.         if (!ign)
  94.             {
  95.             fprintf(stderr, "%s: no such flag: %s\n", argv[0], pv);
  96.             return(EOF);
  97.             }
  98.         else
  99.             pvcon = NULL;
  100.         }
  101.     pvcon = NULL;
  102.     }
  103.     return(NULL);
  104.     }
  105.  
  106.